package com.dragon.modules.yuegou.service.impl.merchant;


import cn.jpush.api.JPushClient;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosAlert;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.modules.yuegou.entity.coupon.MerchantCouponEntity;
import com.dragon.modules.yuegou.entity.coupon.ParkApplyEntity;
import com.dragon.modules.yuegou.entity.merchant.MerchantQrcodeEntity;
import com.dragon.modules.yuegou.entity.merchant.UserJpushEntity;
import com.dragon.modules.yuegou.entity.product.CoupMerchantCouponEntity;
import com.dragon.modules.yuegou.entity.product.CoupTemplateEntity;
import com.dragon.modules.yuegou.entity.product.CoupTemplateSkuRefEntity;
import com.dragon.modules.yuegou.enums.code.MerchantCode;
import com.dragon.modules.yuegou.enums.code.ParkCode;
import com.dragon.modules.yuegou.enums.coupon.CouponSourceType;
import com.dragon.modules.yuegou.enums.coupon.MerchantCouponGrantType;
import com.dragon.modules.yuegou.enums.merchant.MerchantQrcodeStatus;
import com.dragon.modules.yuegou.enums.merchant.MerchantQrcodeType;
import com.dragon.modules.yuegou.enums.merchant.UserJpushType;
import com.dragon.modules.yuegou.enums.order.OrderType;
import com.dragon.modules.yuegou.enums.product.CoupMemberRecordType;
import com.dragon.modules.yuegou.mapper.merchant.MerchantQrcodeMapper;
import com.dragon.modules.yuegou.model.coupon.Coupon;
import com.dragon.modules.yuegou.model.coupon.MerchantCouponGrant;
import com.dragon.modules.yuegou.model.order.Order;
import com.dragon.modules.yuegou.model.product.CoupMemberRecord;
import com.dragon.modules.yuegou.query.coupon.MerchantCouponQuery;
import com.dragon.modules.yuegou.query.merchant.MerchantQrcodeQuery;
import com.dragon.modules.yuegou.query.merchant.UserJpushQuery;
import com.dragon.modules.yuegou.query.product.CoupTemplateSkuRefQuery;
import com.dragon.modules.yuegou.service.coupon.CouponService;
import com.dragon.modules.yuegou.service.coupon.MerchantCouponGrantService;
import com.dragon.modules.yuegou.service.coupon.MerchantCouponService;
import com.dragon.modules.yuegou.service.coupon.ParkApplyService;
import com.dragon.modules.yuegou.service.merchant.MerchantQrcodeService;
import com.dragon.modules.yuegou.service.merchant.UserJpushService;
import com.dragon.modules.yuegou.service.order.OrderService;
import com.dragon.modules.yuegou.service.product.CoupApplyService;
import com.dragon.modules.yuegou.service.product.CoupMemberRecordService;
import com.dragon.modules.yuegou.service.product.CoupMerchantCouponService;
import com.dragon.modules.yuegou.service.product.CoupTemplateService;
import com.dragon.modules.yuegou.service.product.CoupTemplateSkuRefService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 商户停车券二维码表 服务实现
 *
 * @author pbuilder generated
 * @date 2019-05-31 11:06:54
 * @version 2.0
 */
@Slf4j
@Service("merMerchantQrcodeService")
public class MerchantQrcodeServiceImpl extends ServiceImpl<MerchantQrcodeMapper, MerchantQrcodeEntity> implements MerchantQrcodeService {

	@Autowired
	private CouponService couponService;

	@Autowired
	private MerchantCouponService merchantCouponService;

	@Autowired
	private MerchantCouponGrantService merchantCouponGrantService;

	@Autowired(required = false)
	private JPushClient jpushClient;

	@Autowired
	private UserJpushService userJpushService;

	@Autowired
	private CoupMerchantCouponService coupMerchantCouponService;

	@Autowired
	private CoupTemplateSkuRefService coupTemplateSkuRefService;

	@Autowired
	private OrderService orderService;

	@Autowired
	private CoupTemplateService coupTemplateService;

	@Autowired
	private CoupMemberRecordService coupMemberRecordService;

	@Autowired
	private CoupApplyService coupApplyService;

	@Autowired
	private ParkApplyService parkApplyService;

	@Override
	@Transactional
	public boolean scanParkCoupon(String merchantQrcodeId, Integer platform, String memberId) {
		MerchantQrcodeEntity merchantQrcode = getById(merchantQrcodeId);
		if (StringUtils.isEmpty(merchantQrcode.getId())) {
			throw new DragonException(MerchantCode.INVALID_MERCHANT_QRCODE);
		}
		if (MerchantQrcodeStatus.RECEIVE.equals(merchantQrcode.getStatus())) {
			throw new DragonException(ParkCode.PARK_COUPON_RECEIVED);
		}

		MerchantQrcodeQuery qrcodeQuery = new MerchantQrcodeQuery();
		qrcodeQuery.setId(merchantQrcode.getId());
		qrcodeQuery.setStatus(MerchantQrcodeStatus.READY);

		MerchantQrcodeType qrcodeType = merchantQrcode.getType();
		//停车券
		if (MerchantQrcodeType.PARK.equals(qrcodeType)) {
			MerchantCouponEntity merchantCoupon = merchantCouponService.getById(merchantQrcode.getMerchantCouponId());

			if (MerchantQrcodeStatus.RECEIVE.equals(merchantQrcode.getStatus())) {
				throw new DragonException(ParkCode.PARK_COUPON_RECEIVED);
			}

			merchantCoupon.setGranted(merchantCoupon.getGranted() + 1);
			merchantCoupon.setStock(merchantCoupon.getTotal() - merchantCoupon.getGranted());
			MerchantCouponQuery query = new MerchantCouponQuery();
			query.setId(merchantCoupon.getId());
			query.setVersion(merchantCoupon.getVersion());
			merchantCoupon.setVersion(merchantCoupon.getVersion() + 1);
			log.debug("old -> new version {}->{}", query.getVersion(), merchantCoupon.getVersion());
			merchantQrcode.setStatus(MerchantQrcodeStatus.RECEIVE);

			if (merchantCouponService.update(merchantCoupon, query.toQueryWrapper()) && update(merchantQrcode, qrcodeQuery.toQueryWrapper())) {
				Coupon coupon = couponService.createCoupon(null, memberId, merchantCoupon.getMerchantId(),
						merchantCoupon.getCouponTemplateId(), CouponSourceType.MERCHANT);
				MerchantCouponGrant grant = new MerchantCouponGrant();
				grant.setMerchantCouponId(merchantCoupon.getId());
				grant.setMerchantId(merchantCoupon.getMerchantId());
				grant.setMemberId(memberId);
				grant.setCouponId(coupon.getId());
				grant.setParkApplyId(merchantCoupon.getParkApplyId());
				merchantCouponGrantService.save(grant);

				// 停车券领取成功推送极光消息
				this.pushMessage(merchantCoupon.getMerchantId(), merchantQrcodeId,"停车券领取","用户领取停车券成功");
				return true;
			}
		}
		//优惠券
		else if (MerchantQrcodeType.COUPON.equals(qrcodeType)){
			String merchantCouponId = merchantQrcode.getMerchantCouponId();
			MerchantCouponEntity merchantCoupon = merchantCouponService.getById(merchantCouponId);
			merchantQrcode.setStatus(MerchantQrcodeStatus.RECEIVE);
			merchantCoupon.setGranted(merchantCoupon.getGranted() + 1);
			merchantCoupon.setStock(merchantCoupon.getTotal() - merchantCoupon.getGranted());
			MerchantCouponQuery query = new MerchantCouponQuery();
			query.setId(merchantCoupon.getId());
			query.setVersion(merchantCoupon.getVersion());
			merchantCoupon.setVersion(merchantCoupon.getVersion() + 1);
			log.debug("old -> new version {}->{}", query.getVersion(), merchantCoupon.getVersion());
			if (merchantCouponService.update(merchantCoupon, query.toQueryWrapper()) && update(merchantQrcode, qrcodeQuery.toQueryWrapper())){
				Coupon coupon = scanCoupMembers(merchantCoupon, memberId);
				MerchantCouponGrant grant = new MerchantCouponGrant();
				grant.setMerchantCouponId(merchantCoupon.getId());
				grant.setMerchantId(merchantCoupon.getMerchantId());
				grant.setMemberId(memberId);
				grant.setType(MerchantCouponGrantType.DISCOUNT);
				grant.setCouponId(coupon.getId());
				grant.setParkApplyId(merchantCoupon.getParkApplyId());
				merchantCouponGrantService.save(grant);
				//使用数量
				String parkApplyId = merchantCoupon.getParkApplyId();
				ParkApplyEntity parkApply = parkApplyService.getById(parkApplyId);
				parkApply.setUseNum(parkApply.getUseNum()+1);
				parkApplyService.updateById(parkApply);
				this.pushMessage(merchantCoupon.getMerchantId(), merchantQrcodeId,"优惠券领取","用户领取优惠券成功");
				return true;

			}
		}
		//商品券
		else if (MerchantQrcodeType.PRODUCT.equals(qrcodeType)){
			merchantQrcode.setStatus(MerchantQrcodeStatus.RECEIVE);
			if ( update(merchantQrcode, qrcodeQuery.toQueryWrapper())) {
				scanShopMembers(merchantQrcode,memberId);
				this.pushMessage(merchantQrcode.getMerchantId(), merchantQrcodeId,"商品券领取","用户领取商品券成功");
				return true;
			}
		}
		throw new DragonException(ParkCode.PARK_COUPON_RECEIVED);

	}

	private void scanShopMembers(MerchantQrcodeEntity merchantQrcode, String memberId) {
		String coupMerchantCouponId = merchantQrcode.getMerchantCouponId();
		CoupMerchantCouponEntity coupon = coupMerchantCouponService.getById(coupMerchantCouponId);
		String templateId = coupon.getCoupTemplateId();
		String merchantId = coupon.getMerchantId();
		String applyId = coupon.getCoupApplyId();
		CoupTemplateEntity template = coupTemplateService.getById(templateId);
		String busdId = template.getBusdId();
		CoupTemplateSkuRefQuery query = new CoupTemplateSkuRefQuery();
		query.setCoupTemplateId(templateId);
		List<CoupTemplateSkuRefEntity> list = coupTemplateSkuRefService.list(query.toQueryWrapper());
		Map<String, List<CoupTemplateSkuRefEntity>> map = list.stream().collect(Collectors.groupingBy(CoupTemplateSkuRefEntity::getSkuId));
		//修改商户商品券表库存变化
		coupMerchantCouponService.changeStock(coupMerchantCouponId, 1);
		//修改商品券申请表数量
		coupApplyService.changeReleased(applyId, 1);
		for (Map.Entry<String,List<CoupTemplateSkuRefEntity>> entry : map.entrySet()) {
			String skuId = entry.getKey();
			List<CoupTemplateSkuRefEntity> templateSkuRefs = entry.getValue();
			Integer num = templateSkuRefs.stream().map(CoupTemplateSkuRefEntity::getQuantity).reduce(Integer::sum).orElse(0);
			Order order = orderService.createNullOrder(skuId, memberId,busdId, OrderType.COUPON, true, num);
			//创建会员领取记录
			CoupMemberRecord coupMemberRecord = new CoupMemberRecord();
			coupMemberRecord.setMerchantCoupId(coupMerchantCouponId);
			coupMemberRecord.setCoupTemplateId(templateId);
			coupMemberRecord.setOrderNo(order.getId());
			coupMemberRecord.setType(CoupMemberRecordType.UNUSE);
			coupMemberRecord.setMerchantId(merchantId);
			coupMemberRecord.setQuantity(1);
			coupMemberRecord.setMemberId(memberId);
			coupMemberRecord.setDrawTime(LocalDateTime.now());
			coupMemberRecordService.save(coupMemberRecord);
		}
	}

	/****
	 * 领取优惠券
	 * @param merchantCoupon
	 * @param memberId
	 */
	private Coupon scanCoupMembers(MerchantCouponEntity merchantCoupon, String memberId) {
		String couponTemplateId = merchantCoupon.getCouponTemplateId();
		return couponService.createCoupon(null, memberId, couponTemplateId, CouponSourceType.RECEIVE);
	}

	private void pushMessage(String merchantId, String merchantQrcodeId, String title, String body) {
		try {
			log.debug("获取极光商户信息");
			List<String> merchantIds = new ArrayList<>();
			UserJpushQuery userJpushQuery = new UserJpushQuery();
			merchantIds.add(merchantId);
			userJpushQuery.merchantId().in(merchantIds);
			userJpushQuery.setStatus(false);
			List<UserJpushEntity> userJpushList = userJpushService.list(userJpushQuery.toQueryWrapper());

			if (CollectionUtils.isNotEmpty(userJpushList)) {
				for (UserJpushEntity userJpush : userJpushList) {
					if (org.apache.commons.lang3.StringUtils.isNotEmpty(userJpush.getJpushId())) {
						if (UserJpushType.IOS.equals(userJpush.getType())) {
							jpushClient.sendPush(PushPayload.newBuilder().setPlatform(Platform.ios())
									.setAudience(Audience.registrationId(userJpush.getJpushId()))
									.setNotification(Notification.newBuilder().addPlatformNotification(IosNotification
											.newBuilder()
											.setAlert(IosAlert.newBuilder().setTitleAndBody(title, "", body).build())
											.addExtra("from", "TCQ").addExtra("type", "400")
											.addExtra("merchantQrcodeId", merchantQrcodeId).build()).build())
									.build());
							log.debug("ios发送一条推送");
						} else {
							jpushClient.sendPush(PushPayload.newBuilder().setPlatform(Platform.android())
									.setAudience(Audience.registrationId(userJpush.getJpushId()))
									.setNotification(Notification.newBuilder()
											.addPlatformNotification(AndroidNotification.newBuilder().setAlert("")
													.addExtra("merchantQrcodeId", merchantQrcodeId).addExtra("from", "TCQ")
													.addExtra("type", "400").build())
											.build())
									.build());
							log.debug("android发送一条推送");
						}
					}
				}
			}
		} catch (Exception e) {
			log.error("极光推送，发送消息失败", e);
		}
	}
}